package sfeir.ergosum.tools;

import sfeir.ergosum.R;
import sfeir.ergosum.dao.DatabaseConnection;
import sfeir.ergosum.dao.DatabaseProvider;
import sfeir.ergosum.model.Address;
import sfeir.ergosum.model.Email;
import sfeir.ergosum.model.Person;
import sfeir.ergosum.model.Tel;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.provider.Contacts;
import android.provider.Contacts.ContactMethods;
import android.provider.Contacts.People;
import android.provider.Contacts.Phones;

public class ImportContacts {

    private final Handler mHandler;

    public ImportContacts(Handler mHandler) {
        this.mHandler = mHandler;
    }

    public void importAllContacts(final Activity activity)
            throws InterruptedException {
        final ContentResolver resolver = activity.getContentResolver();
        final Uri uri = Contacts.People.CONTENT_URI;
        String[] projection = new String[] { People._ID, People.NAME,
                People.NOTES, People.NUMBER };
        final Cursor cur = resolver.query(uri, projection, null, null, null);
        activity.startManagingCursor(cur);
        final ProgressDialog mProgressDialog = new ProgressDialog(activity);

        final Thread mThread = new Thread() {
            public void run() {
                DatabaseProvider dp = null;
                try {
                    dp = new DatabaseProvider(new DatabaseConnection(activity
                            .getApplicationContext()));
                    dp.open();
                    Person p = null;

                    if (cur.moveToFirst()) {
                        do {
                            p = addContact(cur, resolver);
                            if (p != null)
                                dp.addContact(p, p.getUrl());
                            if (cur != null && mProgressDialog != null)
                                mProgressDialog.setProgress(cur.getPosition());
                        } while (cur.moveToNext());
                    }
                } finally {

                    dp.close();
                    cur.close();
                }
                mProgressDialog.dismiss();
                if (null != mHandler)
                    mHandler.obtainMessage(R.id.hive_reset).sendToTarget();
            }
        };
        mProgressDialog.setTitle(R.string.add_contact_wait_url);
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        if (cur != null && mProgressDialog != null)
            mProgressDialog.setMax(cur.getCount());
        mProgressDialog.setButton2(activity.getText(R.string.dialog_cancel),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        mThread.stop();
                        mProgressDialog.dismiss();
                    }
                });
        mProgressDialog.setIcon(R.drawable.icon);
        mProgressDialog.show();
        mThread.start();
    }

    public Person importContact(Uri url, final ContentResolver resolver) {
        String[] projection = new String[] { People._ID, People.NAME,
                People.NOTES, People.NUMBER };
        final Cursor cur = resolver.query(url, projection, null, null, null);
        Person p = null;
        if (cur.moveToFirst()) {
            do {
                p = addContact(cur, resolver);
            } while (cur.moveToNext());
        }
        cur.close();
        return p;
    }

    protected Person addContact(Cursor cur, ContentResolver resolver) {
        String name = cur.getString(cur.getColumnIndex(People.NAME));
        String id = cur.getString(cur.getColumnIndex(Contacts.People._ID));
        String notes = cur.getString(cur.getColumnIndex(People.NOTES));
        Person p = null;
        if (name != null && !name.equalsIgnoreCase("")) {
            p = new Person();

            // firstname name
            int n = name.indexOf(" ");
            if (n != (-1)) {
                String first = name.substring(0, n);
                String last = name.substring(n);

                p.setName(last);
                p.setFirstname(first);
            } else {
                p.setName(name);
                p.setFirstname("");
            }

            if (notes != null)
                p.setAboutMe(notes);
        }

        p = addContactMethodsToPerson(resolver, id, p);
        if (p != null) {
            addPhonesToContact(resolver, id, p);

            String url = "content://contacts/people/" + id;
            p.setPhoto(url);

            p.setUrl(url);
        }
        return p;
    }

    /**
     * Emails and postal addresses
     * 
     * @param activity
     * @param resolver
     * @param projection
     * @param id
     * @param p
     */
    private Person addContactMethodsToPerson(ContentResolver resolver,
            String id, Person p) {

        Uri mailsUri = Contacts.ContactMethods.CONTENT_URI;
        Cursor curCM = resolver.query(mailsUri, null, "person=" + id, null,
                null);
        // activity.startManagingCursor(curCM);

        if (curCM.moveToFirst()) {
            int cmType;
            String cmContent;
            int kind;
            do {
                kind = curCM.getInt(curCM.getColumnIndex(ContactMethods.KIND));
                cmType = curCM
                        .getInt(curCM.getColumnIndex(ContactMethods.TYPE));
                cmContent = curCM.getString(curCM
                        .getColumnIndex(ContactMethods.DATA));

                /*
                 * EMAILS informations
                 */
                if (kind == Contacts.KIND_EMAIL) {
                    Email e = new Email(cmContent);
                    if (cmType != 0) {
                        switch (cmType) {
                        case Contacts.ContactMethods.TYPE_HOME:
                            e.setTypeEmail(Email.PERSONAL_EMAIL);
                            break;
                        case Contacts.ContactMethods.TYPE_WORK:
                            e.setTypeEmail(Email.PROFESSIONNAL_EMAIL);
                            break;
                        default:
                            e.setTypeEmail(Email.UNKNOWN);
                        }
                    }
                    if (p == null || p.getName() == null
                            || p.getName().equalsIgnoreCase("")) {
                        p = new Person();
                        p.setFirstname("");
                        String name = e.getEmail();
                        // firstname name
                        int n = name.indexOf("@");
                        if (n != (-1)) {
                            String firstname = name.substring(0, n);
                            p.setName(firstname);
                        } else {
                            p.setName(name);
                        }

                    }
                    if (p != null)
                        p.getEmails().add(e);
                }
                /*
                 * POSTAL ADDRESSES
                 */
                if (kind == Contacts.KIND_POSTAL) {
                    Address a = new Address(cmContent);
                    if (cmType != 0) {
                        switch (cmType) {
                        case Contacts.ContactMethods.TYPE_HOME:
                            a.setType(Address.PERSONAL_ADDRESS);
                            break;
                        case Contacts.ContactMethods.TYPE_WORK:
                            a.setType(Address.PROFESSIONNAL_ADDRESS);
                            break;
                        default:
                            a.setType(Address.DEFAULT_ADDRESS);
                        }
                    }
                    if (p != null)
                        p.getAddresses().add(a);
                }
            } while (curCM.moveToNext());
        }
        curCM.close();
        return p;
    }

    /**
     * Phone numbers
     * 
     * @param activity
     * @param resolver
     * @param id
     * @param p
     */
    private void addPhonesToContact(ContentResolver resolver, String id,
            Person p) {
        /*
         * PHONES informations
         */
        Uri phonesUri = Contacts.Phones.CONTENT_URI;
        String[] projection = new String[] { Phones.TYPE, Phones.NUMBER };
        Cursor curPhone = resolver.query(phonesUri, projection, "person=" + id,
                null, null);
        // activity.startManagingCursor(curPhone);
        Tel t = null;
        if (curPhone.moveToFirst()) {
            int type;
            String number;
            do {
                type = curPhone.getInt(curPhone
                        .getColumnIndex(Contacts.Phones.TYPE));
                number = curPhone.getString(curPhone
                        .getColumnIndex(Contacts.Phones.NUMBER));

                if (number != null && !number.equalsIgnoreCase("")) {
                    t = new Tel();
                    t.setPhoneNumber(number);
                }
                if (type != 0) {
                    switch (type) {
                    case Contacts.Phones.TYPE_MOBILE:
                        t.setType(Tel.MOBILE_LINE);
                        break;
                    case Contacts.Phones.TYPE_HOME:
                        t.setType(Tel.HOME_LANDLINE);
                        break;
                    case Contacts.Phones.TYPE_WORK:
                        t.setType(Tel.PROFESSIONNAL_LINE);
                    default:
                        t.setType(Tel.UNKNOWN_LINE);
                    }
                }
                p.getTels().add(t);
            } while (curPhone.moveToNext());
        }

        curPhone.close();
    }
}
